package cn.dakaqi.api.qnzyz.util;

import cn.dakaqi.utils.DateUtil;
import cn.dakaqi.utils.base64.RSAUtils;
import cn.dakaqi.utils.http.HttpsUtil;
import cn.dakaqi.utils.redis.RedisClientTemplate;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Authoer:chunyang
 * ProjectName:Volunteer
 * Date: 2015/7/6.
 * Description:
 */
@Component
public class BHAccesssToken
{
    @Autowired
    RedisClientTemplate redisClientTemplate;
    public String getAccessToken(String clientID)
    {
        String token = null;
        try
        {
            //String val[] = getToken(clientID);
            String key = "APP-"+clientID + "-TOKEN";
            if(redisClientTemplate.hkeys(key).isEmpty())
            {
                token = setTokenCache(key, clientID);
            }
            else
            {
                if(redisClientTemplate.ttl(key)<=120)
                    token = setTokenCache(key,clientID);
                else
                    token = redisClientTemplate.hget(key, clientID);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            return token;
        }

    }
    public void refreshToken(String clientID)
    {
        String key = "APP-"+clientID + "-TOKEN";
        redisClientTemplate.del(key);

        getAccessToken(clientID);
    }
    private String setTokenCache(String key,String clientID)
    {
        String token = null;
        String val[] = getToken(clientID);
        if(null != val && val.length == 2)
        {
            token = val[0];
            String expireTime = val[1];
            Map<String,String> map = new HashMap<String, String>();
            map.put(clientID, token);
            redisClientTemplate.hmset(key,map);
            int second = get2DatesSecond(expireTime);
            redisClientTemplate.expire(key, second);
        }
        return token;
    }
    private int get2DatesSecond(String expireTime)
    {
        int second = 0;
        try
        {
            Calendar start= Calendar.getInstance();
            start.setTime(new Date());
            Calendar end = Calendar.getInstance();
            end.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(expireTime));
            second =(int)end.getTime().getTime()/1000-(int)start.getTime().getTime()/1000;
        } catch (ParseException e)
        {
            e.printStackTrace();
        }
        return second;
    }
    private String[] getToken(String clientID)
    {
        String[] val = null;
        String param = "client_id=" + clientID + "&info="+encryptInfo(clientID);
        String postUrl = BHConstant.checkNetWork()+"/token?"+param;
        try
        {
            val = pareAccessToken(clientID, HttpsUtil.post(postUrl, param));
        }catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            return val;
        }

    }
    private String[] pareAccessToken(String clientID,String result)
    {
        String val[] = null;
        try
        {
            if(result != null && !result.trim().equals(""))
            {
                JSONObject jsonObject = JSON.parseObject(result);
                if(jsonObject != null)
                {
                    int res_code = jsonObject.getIntValue("ret");
                    //String msg = jsonObject.getString("msg");
                    if(res_code == 0)
                    {
                        val = new String[2];
                        JSONObject jsonObject2 = jsonObject.getJSONObject("result");
                        String token = jsonObject2.getString("token");
                        //System.out.println("token--1->" + token);
                        token = decryptInfo(clientID,token);
                        //System.out.println("token--2->" + token);
                        String expireTime = jsonObject2.getString("expireTime");
                        //System.out.println("expireTime--->" + expireTime);
                        val[0] = token;
                        val[1] = expireTime;
                    }
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            return val;
        }

    }

    private String decryptInfo(String clientID,String token)
    {
        byte[] encodedData = null;
        String val = "";
        try
        {
            byte[] data = token.getBytes();
            encodedData = RSAUtils.decryptByPublicKey(Base64.decodeBase64(data), BHConstant.PUBLICKEY);
            val = new String(encodedData,"UTF-8");
            System.out.println("加密后文字：\r\n" + val);

        } catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            return val;
        }
        //byte[] decodedData = RSAUtils.decryptByPrivateKey(encodedData, privateKey);
        //String target = new String(decodedData);
        //System.out.println("解密后文字: \r\n" + target);
    }

    private String encryptInfo(String clientID)
    {
        //第一步：用客户号加"|"作为链接后面跟一个6位随机数， 例如987654|123456，
        //第二步：然后再用申请客户号获取的公钥使用RSA算法进行加密。然后对加密结果进行base64编码。
        byte[] encodedData = null;
        String val = "";
        try
        {
            String info = clientID + "|" + DateUtil.currentDateTimeStringTrim();
            byte[] data = info.getBytes();
            encodedData = RSAUtils.encryptByPublicKey(data, BHConstant.PUBLICKEY);
            data = Base64.encodeBase64(encodedData, false, true);
            val = new String(data,"UTF-8");
            System.out.println("加密后文字：\r\n" + val);

        } catch (Exception e)
        {
            e.printStackTrace();
        }
        return val;
        //byte[] decodedData = RSAUtils.decryptByPrivateKey(encodedData, privateKey);
        //String target = new String(decodedData);
        //System.out.println("解密后文字: \r\n" + target);
    }

//    public static String sign(String unsigned)
//    {
//        try {
//            String md5bytes = DigestUtils.md5Hex(unsigned);
//            PrivateKey privateKey = keyReader.readPublicKey(keyStr, base64Encoded, algorithmName);
//            Cipher cipher = Cipher.getInstance("RSA");
//            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
//            //私钥加密
//            byte[] result = cipher.doFinal(md5bytes.getBytes());
//            //base64加密
//            return StringUtil.replace(Base64Utils.encode(result), LINE_BREAK, "");
//        } catch (NoSuchAlgorithmException e) {
//            e.printStackTrace();
//        } catch (NoSuchPaddingException e) {
//            e.printStackTrace();
//        } catch (InvalidKeyException e) {
//            e.printStackTrace();
//        } catch (IllegalBlockSizeException e) {
//            e.printStackTrace();
//        } catch (BadPaddingException e) {
//            e.printStackTrace();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//
//        return null;
//    }

}
